package org.colafries.admin.service.impl.index;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.logging.log4j.util.Strings;
import org.colafries.admin.entity.domain.index.LogicDimRelation;
import org.colafries.admin.entity.domain.index.LogicDimension;
import org.colafries.admin.entity.domain.index.LogicFactTable;
import org.colafries.admin.entity.vo.index.LogicDimRelationReqVO;
import org.colafries.admin.exceptions.ServiceException;
import org.colafries.admin.exceptions.enums.ErrorCodeEnum;
import org.colafries.admin.mapper.index.LogicDimRelationMapper;
import org.colafries.admin.service.index.ILogicDimRelationService;
import org.colafries.admin.service.index.ILogicDimensionService;
import org.colafries.admin.service.index.ILogicFactTableService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 逻辑维度关系表 服务实现类
 * </p>
 *
 * @author Ann
 * @since 2024-06-14
 */
@Service("ILogicDimRelationServiceImpl")
public class ILogicDimRelationServiceImpl extends ServiceImpl<LogicDimRelationMapper, LogicDimRelation> implements ILogicDimRelationService {

    @Resource
    ILogicFactTableService iLogicFactTableService;

    @Resource
    ILogicDimensionService iLogicDimensionService;

    @Override
    public int add(LogicDimRelationReqVO reqVO) {
        validateReqVO(reqVO);
        LogicDimRelation logicDimRelation = LogicDimRelation.builder()
                .logicDimensionCode(reqVO.getLogicDimensionCode())
                .logicTableCode(reqVO.getLogicTableCode())
                .expression(reqVO.getExpression())
                .createUser(reqVO.getCreateUser())
                .updateUser(reqVO.getUpdateUser())
                .build();
        return baseMapper.insert(logicDimRelation);
    }

    @Override
    public int update(LogicDimRelationReqVO reqVO) {
        validateReqVO(reqVO);
        LogicDimRelation oldLogicDimRelation = validateRelExists(reqVO);
        LogicDimRelation newLogicDimRelation = LogicDimRelation.builder()
                .id(oldLogicDimRelation.getId())
                .logicDimensionCode(reqVO.getLogicDimensionCode())
                .logicTableCode(reqVO.getLogicTableCode())
                .expression(reqVO.getExpression())
                .updateUser(reqVO.getUpdateUser())
                .build();
        return baseMapper.updateById(newLogicDimRelation);
    }

    @Override
    public List<LogicDimRelation> listAll(LogicDimRelationReqVO reqVO) {
        LambdaQueryWrapper<LogicDimRelation> queryWrapper = new LambdaQueryWrapper<>();
        List<LogicDimRelation> relations = baseMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(relations)){
            return Collections.emptyList();
        }
        //
        relations.sort(Comparator.comparing(LogicDimRelation::getLogicDimensionCode));
        //
        return relations.stream().peek(relation -> {
            LogicDimension dimension = iLogicDimensionService.queryByCode(relation.getLogicDimensionCode());
            if (dimension == null) {
                relation.setLogicDimField(Strings.EMPTY);
                return;
            }
            relation.setLogicDimField(dimension.getField());
            LogicFactTable logicFactTable = iLogicFactTableService.queryByCode(relation.getLogicTableCode());
            if (logicFactTable == null) {
                relation.setLogicTableName(Strings.EMPTY);
                return;
            }
            relation.setLogicTableName(logicFactTable.getLogicTableName());
        }).collect(Collectors.toList());
    }

    /**
     * 根据逻辑维度code查询关联逻辑表字段
     *
     * @param dimensionCode
     * @return java.util.List<org.colafries.admin.entity.domain.index.LogicDimRelation>
     * @Author anning
     * @Date 2024/6/21
     */
    @Override
    public List<LogicDimRelation> listByDimensionCode(Long dimensionCode) {
        return baseMapper.selectList(
                Wrappers.<LogicDimRelation>lambdaQuery().eq(LogicDimRelation::getLogicDimensionCode, dimensionCode)
        );
    }

    @Override
    public int delete(LogicDimRelationReqVO reqVO) {
        LogicDimRelation logicDimRelation = validateRelExists(reqVO);
        return baseMapper.deleteById(logicDimRelation.getId());
    }

    private LogicDimRelation validateRelExists(LogicDimRelationReqVO reqVO) {
        LogicDimRelation logicDimRelation = this.getById(reqVO.getId());
        if (logicDimRelation == null) {
            log.warn("删除逻辑维度关系失败，逻辑维度关系不存在 id:" + reqVO.getId());
            throw new ServiceException(ErrorCodeEnum.GL999999, "删除逻辑维度关系失败，逻辑维度关系不存在 id:" + reqVO.getId());
        }
        return logicDimRelation;
    }

    /**
     * 请求参数验证
     *
     * @param reqVO
     * @return void
     * @Author anning
     * @Date 2024/6/14
     */
    private void validateReqVO(LogicDimRelationReqVO reqVO) {
        // 维度code检查
        Long logicDimensionCode = reqVO.getLogicDimensionCode();
        LogicDimension logicDimension = iLogicDimensionService.queryByCode(logicDimensionCode);
        if (logicDimension == null) {
            log.warn("新增逻辑维度关系失败，逻辑维度不存在 code:" + logicDimensionCode);
            throw new ServiceException(ErrorCodeEnum.GL999999, "新增逻辑维度关系失败，逻辑维度不存在 code:" + logicDimensionCode);
        }

        // 逻辑事实表code检查
        Long logicTableCode = reqVO.getLogicTableCode();
        LogicFactTable logicFactTable = iLogicFactTableService.queryByCode(logicTableCode);
        if (logicFactTable == null) {
            log.warn("新增逻辑维度关系失败，逻辑事实表不存在 code:" + logicTableCode);
            throw new ServiceException(ErrorCodeEnum.GL999999, "新增逻辑维度关系失败，逻辑事实表不存在 code:" + logicTableCode);
        }
    }
}
